home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / basic / pbasmlib.zip / EMS.DOC < prev    next >
Text File  |  1994-02-12  |  16KB  |  315 lines

  1. PBASMLIB Assembly Language Routines for PB3C
  2. Version 1.0
  3. Expanded Memory (EMS) Module
  4. (C) Copyright 1994 by Tim Gerchmez
  5. All Rights Reserved.
  6.  
  7. This module interfaces you to EMS (Expanded Memory) in your computer,
  8. if it is available and an EMS driver is loaded.  You will be able to
  9. access any or all of these routines by including the statements
  10. $INCLUDE "PBASMLIB.INC" and $LINK "PBASMLIB.PBL" at the top of your
  11. PowerBASIC programs.  An interface to XMS (Extended Memory) is included
  12. in a separate module.
  13.  
  14. Many of these commands let you access EMS memory at a very low level.  For
  15. an easier way to access EMS memory, see EMSPUTSTRING and EMSGETSTRING.
  16.  
  17. PowerBASIC is an ideal language to use EMS with because of its ability
  18. to utilize absolute arrays.  EMS memory is mapped into a section of memory
  19. physically accessible to the CPU, and you can map a PowerBASIC array into
  20. this "Page Frame" segment for direct access to EMS!  Just use the EMSPAGEFRAME
  21. function to find the page frame segment, then DIM an ABSOLUTE array AT the correct
  22. segment of memory (see the PB online help for further information on the DIM ABSOLUTE
  23. array AT sequence).  The following is an example:
  24.  
  25. pf?? = emspageframe  'Get the EMS page frame in your system
  26. dim absolute arry%(0 to 32767) at pf??  'DIM an integer array at page frame.
  27.                                         'You are not restricted to an integer
  28.                                         'array, but could use byte or word arrays
  29.                                         '(or other numerics) instead.  Integers are
  30.                                         'convenient because they are fast, easy to
  31.                                         'manipulate, and use two bytes per number,
  32.                                         'which fills the 64K page frame perfectly
  33.                                         '(32768 * 2 = 64K).
  34.  
  35. The newest versions of MS-DOS include Expanded/Extended Memory drivers that
  36. let you use EMS or XMS interchangeably (they fool the program into thinking
  37. that a large quantity of both is available, while one or the other "decreases"
  38. as the other kind of memory is used).  Given the choice, and given PowerBASIC's
  39. ability to use DIM ABSOLUTE for arrays, it's recommended that you use EMS memory
  40. whenever possible.  You can, however, use either or both with modern versions of
  41. DOS and computers that contain XMS memory and a memory manager that emulates EMS
  42. memory.
  43.  
  44. Caution: PB does not seem to like you playing with EMS memory while in the
  45.          IDE.  I have gotten EMM386 error #12, followed by an automatic reboot,
  46.          when accessing EMS while in the IDE.  You might test this on your system
  47.          to see if you get the same results.  If you do, be sure to use EMS routines
  48.          only in a standalone .EXE file.
  49.  
  50.  
  51. The following is a list of error codes that may be returned
  52. by function EMSERROR:
  53.  
  54. 128  Internal error in EMM software     146  Source and target overlap
  55. 129  Malfunction in EMS hardware        147  Illegal region length
  56. 130  Memory manager busy                148  Region overlap
  57. 131  Invalid handle                     149  Offset outside logical page
  58. 132  Function not defined               150  Region length > 1MB
  59. 133  No more handles available          151  Cannot exchange overlap
  60. 134  Error in mapping context           152  Memory types undefined
  61. 135  Not enough pages exist             153  Not used
  62. 136  Not enough pages available         154  ARS not supported
  63. 137  Cannot allocate zero pages         155  ARS currently allocated
  64. 138  Page not allocated to handle       156  ARS not zero
  65. 139  Illegal physical page number       157  ARS not allocated
  66. 140  Save state area full               158  DMA channels not supported
  67. 141  Save of mapping context failed     159  Illegal DMA channel
  68. 142  Restore of mapping context failed  160  No handle for this name
  69. 143  Subfunction parameter not defined  161  Name already exists
  70. 144  Attribute type not defined         162  Memory address wrap
  71. 145  Feature not supported              163  Invalid pointer
  72. 240  String too long (EMS Module Internal)
  73.  
  74. ================================================================================
  75. function emsactivehandles
  76.  
  77. Returns the number of currently active EMS handles in use.
  78. The number of active EMM handles will never exceed 255.  If
  79. this function encounters an error, it can be checked with EMSERROR.
  80.  
  81. Example: print emsactivehandles
  82.  
  83. ================================================================================
  84. sub emsalloc(pg??,h??)
  85.  
  86. Allocates a certain number of EMS pages (16K per page), and returns
  87. a handle to be used in future accesses to those pages.  Be sure to
  88. check if there's any EMS available with EMSFREE first, and use the
  89. function EMSERROR afterwards to make sure there was no error encountered.
  90.  
  91. pg??: Set to total number of EMS pages (16K per page) to allocate
  92. h??: Returns a handle if allocation was successful, or zero/
  93.      undefined if error (see example below).
  94.  
  95. Example: emsalloc 2,h??  'Allocates 32K of memory (2 16K pages)
  96.          if emserror = 0 then print "32K EMS allocated successfully."
  97.  
  98. ================================================================================
  99. sub emsdealloc(h??)
  100.  
  101. Deallocates (releases) the EMS pages currently assigned to a
  102. handle, and releases the handle itself.  Call this function when
  103. you are done using a certain section of EMS.  It is important to
  104. deallocate ALL EMS allocated with EMSALLOC before ending your program,
  105. or that memory will REMAIN allocated until the computer is rebooted.
  106. Use function EMSERROR to check the status of this command after using it.
  107. You can also use this command to deallocate EMS strings allocated with
  108. EMSPUTSTRING (see this command for details).
  109.  
  110. h??: Set to the handle to deallocate (originally returned with EMSALLOC).
  111.  
  112. Example: call emsdealloc(h??) 'Deallocates handle h??
  113.  
  114. ================================================================================
  115. function emsdetect
  116.  
  117. This function checks to see whether an expanded memory manager
  118. (EMM) is installed.  It does not check to see whether the EMM is
  119. activated, or whether EMS memory is actually available.  Use this
  120. function first before calling any of the other functions, as an EMM
  121. driver is a necessity in using Expanded Memory.  This function will
  122. also detect whether an XMS/EMS driver allows EMS (for example, if the
  123. NOEMS option is set with EMM386, zero (not installed) will be returned).
  124.  
  125. Note: For those techies who are interested, this routine uses the
  126. EMMXXXX0 filename method, with a call to IOCTL output status request
  127. for extra security.
  128.  
  129. emsdetect: Returns -1 if Expanded Memory Manager is resident, or 0 if not.
  130.  
  131. Example: if emsdetect then print "EMM detected."
  132.  
  133. ================================================================================
  134. function emserror
  135.  
  136. Returns the status of the last EMS function performed in
  137. the EMS unit.  Will return a zero if no error, or error
  138. code if error (see listing of possible error codes elsewhere
  139. in this document).  Check the status of EMSERROR after every
  140. EMS function that could encounter an error.
  141.  
  142. Example: if emserror then print "EMS Error!":stop
  143.  
  144. ================================================================================
  145. function emsfree
  146.  
  147. Returns total number of 16K EMS pages free.  To find out TOTAL
  148. number of EMS pages instead, use EMSTOTAL.  Returns -1 if error
  149. is encountered, which you can check with EMSERROR.
  150.  
  151. Example: print (16384*emstotal) "Bytes EMS free."
  152.  
  153. ================================================================================
  154. function emsgetstring$(h??)
  155.  
  156. Retrieves a string previously stored in EMS with EMSPUTSTRING,
  157. and deallocates the associated handle.  This routine, or EMSDEALLOC,
  158. must eventually be called after EMSPUTSTRING, or the EMS will remain
  159. allocated until the computer is rebooted.  Many errors may be encountered
  160. in the retrieval process, so be sure to check with EMSERROR after
  161. using this function to be sure the string was recalled properly.
  162. See EMSPUTSTRING for details on how to use that function.
  163.  
  164. h??: Set to handle previously returned by EMSPUTSTRING.  Deallocates
  165.      handle h?? if everything goes correctly (it should).  If you get
  166.      an error with this routine, you may want to call EMSDEALLOC separately
  167.      to be sure handle h?? is deallocated.
  168. emsgetstring$: Returns the string originally passed to EMSPUTSTRING.
  169.  
  170. Example: s$ = emsgetstring$(h??)
  171.          if emserror = 0 the print "String Retrieved."
  172.          if emserror <> 0 then call emsdealloc(h??)  'Insurance
  173.  
  174. ================================================================================
  175. sub emsmap(mp??,ep??,h??)
  176.  
  177. Maps a logical EMS page (16K) onto one of the four physical
  178. pages (16K apiece) in the EMS page frame, effectively storing
  179. the EMS page to the physical page, and associating it with any
  180. changes then made to that physical page.  This concept of "mapping"
  181. can be more confusing than a simple store to/recall from concept,
  182. so let's go over it.  When you map an EMS page to a physical memory
  183. page, the contents of the EMS page are first moved INTO the physical
  184. page.  Think of the physical page as being soft like wet concrete, and
  185. the EMS page being a metal mold.  That EMS page then "softens" and remains
  186. "on top of" the physical memory page, conceptually changing along with the
  187. physical contents every time you write to the physical page.  When you call
  188. this function again to map a NEW EMS page to the current physical page, the
  189. current EMS page is "lifted off of" the physical page and retains its "imprint."
  190. The new EMS page is then "imprinted" into the physical memory, and the process
  191. starts over.  It may help to envision this process in your mind as you read this.
  192. XMS storage is more straightforward in some ways than EMS storage (it uses a normal
  193. store/recall technique rather than the concept of "memory mapping."  Examples of EMS
  194. mapping are included as source code files with PBASMLIB, as a demonstration.
  195.  
  196. mp??: Set to the Physical Page Number (0-3) in the page frame to map EMS to.
  197.       Remember, each physical page is 16K in size.
  198. ep??: Set to the EMS page (each logical page is 16K in length) to map onto the
  199.       physical page you specified in mp??.  This number should be in the range
  200.       of 0 to N-1, where N is the number of pages previously allocated to the
  201.       EMM handle with the EMSALLOC function (next parameter).
  202.  
  203. h??:  Set to the EMS handle associated with the pages you're mapping to physical
  204.       memory.
  205.  
  206. To actually access the physical page frame memory, use function EMSPAGEFRAME
  207. to find the EMS page frame segment address.  You can then use DEF SEG along with
  208. PEEK and POKE, or DIM an ABSOLUTE array AT the value returned by EMSPAGEFRAME.
  209.  
  210. Note: Be sure to use EMSERROR to check if an error occurred after using this routine.
  211.  
  212. Example: emsmap 0,85,h??  'Maps EMS page 85 of handle h?? onto page frame page 0.
  213.  
  214. ================================================================================
  215. function emsowned(h??)
  216.  
  217. Returns the number of 16K EMS pages allocated to a particular
  218. handle.  An EMM handle never has zero pages of memory allocated
  219. to it.  If an error occurs with this routine (invalid handle, for
  220. example), the value 0 will be returned, and error number can be
  221. checked with EMSERROR.
  222.  
  223. Example: print emsowned(h??)
  224.  
  225. ================================================================================
  226. function emspageframe
  227.  
  228. Returns the physical segment of memory the EMM manager maps
  229. EMS memory to.  This will be the area of memory to retrieve
  230. data from once EMS is mapped there.  The EMS page frame area
  231. is 64K in size, and starts at offset zero of the segment
  232. returned by this function.  It consists of four 16K "pages"
  233. that 16K EMS pages can be mapped on to (see EMSMAP).  If 0 is
  234. returned by this function, an error was encountered, which you
  235. should check with function EMSERROR.
  236.  
  237. Example: print emspageframe
  238.  
  239. ================================================================================
  240. sub emsputstring(s$,h??)
  241.  
  242. Saves a string in EMS memory, and returns a handle for later
  243. retrieval of the string.  This is one of the easiest to use EMS
  244. routines in the PBASMLIB EMS unit, and requires only that
  245. you check for the presence of an EMS driver with EMSDETECT.
  246. The routine will check for free EMS memory, allocate a handle
  247. for you, and store the string in EMS.  Many errors can be
  248. encountered along the way, so BE SURE TO CHECK after calling
  249. this routine with the EMSERROR function.  EMSERROR will return
  250. a value of zero if the function was successful, or an error number
  251. listed at the top of this document.
  252.  
  253. NOTE: This routine uses physical page zero (and 1 if needed) of the page
  254.       frame, and maps its own handle's EMS onto that page.  You may need to
  255.       remap your EMS pages back if you're using EMS independent of this routine.
  256.  
  257. s$: Set to string to store, up to a maximum of 32,750 bytes in
  258.     length (make sure to set the $STRING metastatement appropriately).
  259.     Each string passed will be allocated a handle and a FULL 16K of
  260.     EMS memory AT LEAST, so the longer the string, the less memory will
  261.     be wasted (at each 16K boundary).  Note that a string longer than 16K
  262.     will be allocated 32K of EMS memory.  It is suggested that you group
  263.     smaller strings into one long string, use emsputstring, get the string
  264.     back later with EMSGETSTRING, then parse the string back out.
  265.  
  266. h??: Returns an EMS handle for later retrieval of the passed string, if
  267.      everything worked correctly.  If not, h?? will be undefined.
  268.      Note that you must eventually either (1) use EMSGETSTRING to retrieve
  269.      the string (this deallocates handle h?? automatically), or use EMSDEALLOC
  270.      to deallocate h??, or the handle will remain allocated until the computer
  271.      is rebooted.
  272.  
  273. Example: s$="This is a test"  'Short string, lots of EMS wasted
  274.          emsputstring s$,h?? 'Save the string
  275.          if emserror = 0 then print "S$ was stored in EMS memory."
  276.          if emserror <> 0 then print "EMS Error Number";emserror : end
  277.          s$=""  'Deallocate s$, now that it's in EMS.
  278.  
  279. ================================================================================
  280. function emsstatus
  281.  
  282. This function checks whether the installed EMS hardware is
  283. functioning properly.  Be sure to check for the existence of
  284. an expanded memory manager with EMSDETECT before calling this
  285. function.  This function should generally return an ok status
  286. with EMS emulators like EMM386, since XMS hardware is used to
  287. emulate the presence of EMS memory.
  288.  
  289. emsstatus: Returns -1 if hardware ok, or 0 if error (use EMSERROR
  290. to check error code if a zero is returned).
  291.  
  292. Example: if emsstatus = -1 then print "EMS hardware is ok."
  293.  
  294. ================================================================================
  295. function emstotal
  296.  
  297. Returns the total number of logical EMS pages present in the
  298. system (NOT FREE pages).  Each EMS page is 16K in size.  To
  299. find number of pages free, use EMSFREE instead.  Returns -1 if
  300. error occurs, which you can check with EMSERROR.
  301.  
  302. Example: tot?? = emstotal
  303.  
  304. ================================================================================
  305. function emsversion
  306.  
  307. Returns the version number of the EMM driver currently
  308. installed.  The version number is encoded as BCD, and can
  309. be converted by using the HEX$() equivalent (see examples below).
  310. If an error is encountered (unlikely), it can be checked with EMSERROR.
  311.  
  312. Example: print hex$(emsversion) 'Version 4.x of EMM386 prints "40"
  313. Example: v% = val(hex$(emsversion)) 'Get version number in a numeric variable
  314.  
  315.